package com.terabits.smartriver.util;

import com.terabits.smartriver.mapper.ModelMapper;
import org.apache.commons.jexl2.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * Created by Yin on 2019/3/19
 */
@Component
public class CalculationUtils {

    private static ModelMapper modelMapper;

    @Autowired
    public void setModelMapper(ModelMapper modelMapper) {
        CalculationUtils.modelMapper = modelMapper;
    }

    /**
     * ji算公式是否合法 此时变量以替换成数字
     *
     * @param expression
     * @return
     */
    public static String calculation(String expression) {
        CalculationUtils calculation = new CalculationUtils();
        JexlContext jc = new MapContext();
        jc.set("Math", Math.class);
        jc.set("calculation", calculation);
        jc.set("result", "");
//        String result = Math.pow(calculation.conver( "A01") * (calculation.conver( "P01") + 1), 2);

        try {
            //使用引擎创建表达式对象
            Expression e = new JexlEngine().createExpression(expression);
            //计算
            Object evaluate = e.evaluate(jc);
            return evaluate.toString();
        } catch (JexlException jexlException) {
            System.out.println("不合法");
            return null;
        }
    }

    /**
     * 将变量赋值具体数字 检查公式是否合法  $开始符号 #结束符号
     * 例子： result = Math.pow($PH# * ($HCL#+1),2)  ==》 result = Math.pow(4*(2+1),2)
     *
     * @param expression
     * @return
     */
    public static String replace(String expression, Integer type) {
//        result = Math.pow($PH# * ($HCL#+1),2)
        String replaxe = ((int) (Math.random() * 10)) + "";
        if (type != 1) {
            replaxe = "true";
        }

        String[] split = expression.split("#");

        int size = split.length;
        if ("#".equals(expression.substring(expression.length() - 1))) {
            size++;
        }
        for (int i = 0; i < size - 1; i++) {
            String str = split[i].substring(split[i].indexOf("$")) + "#";
            expression = expression.replace(str, replaxe);

        }
        return expression;
    }

    /**
     * 判断是不是操作符是否正确  例: 公式=氮气磷3
     *
     * @param expression
     * @param type
     * @return
     */
    public static String checkOperator(String expression, Integer type) {
        if (type == 1) {
            String[] split = expression.split("#");

            for (int i = 1; i < split.length; i++) {
                String first = split[i].substring(0, 1);
                if ("$".equals(first) || first.matches("\\d+")) {
                    return null;
                }
            }
        }
        return "OK";
    }

    //判断是否是数字
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        //判断是否有小数点
        if (str.indexOf(".") > 0) {
            //判断是否只有一个小数点
            if (str.indexOf(".") == str.lastIndexOf(".") && str.split("\\.").length == 2) {
                return pattern.matcher(str.replace(".", "")).matches();
            } else {
                return false;
            }
        } else {
            return pattern.matcher(str).matches();
        }
    }

    public static double correl(Double[] yVals, Double[] xVals) {
        double rval = 0;
        double Exy = 0;
        double Ex = 0;
        double Ey = 0;
        for (int i = 0; i < xVals.length; i++) {
            Exy += xVals[i] * yVals[i];
            Ex += xVals[i];
            Ey += yVals[i];
        }
        Exy /= yVals.length;
        Ex /= yVals.length;
        Ey /= yVals.length;
        rval = (Exy - Ex * Ey) / (biaoZhunCha(xVals) * biaoZhunCha(yVals));
        return rval;
    }

    //计算和
    public static double calcSum(Double[] list) {
        double sum = 0;
        for (int i = 0; i < list.length; i++) {
            sum += list[i];
        }
        return sum;
    }

    //求平均值
    public static double mean(Double[] list) {
        return calcSum(list) / list.length;
    }

    //求标准差
    public static double biaoZhunCha(Double[] list) {
        double sum = 0;
        //平均数
        double meanValue = mean(list);
        for (int i = 0; i < list.length; i++) {
            sum += Math.pow(list[i] - meanValue, 2);
        }
        return Math.sqrt(sum / list.length);
    }
}
